home *** CD-ROM | disk | FTP | other *** search
- /* Garbage collection */
-
- #include "params.h"
- #include "gambit.h"
- #include "struct.h"
- #include "os.h"
- #include "opcodes.h"
- #include "run.h"
-
-
- /*---------------------------------------------------------------------------*/
-
-
- void gc_flip();
- void gc_scan_range();
-
-
- long gc_report; /* index of '##gc-report' variable */
-
-
- #ifdef DEBUG_GC
- SCM_obj scanned_object;
- void show_state();
- #endif
-
-
- void gc()
- { char *nb, *nt; /* new space bottom and top */
- SCM_obj *fb, *ft; /* free space bottom and top */
- long cpu_times1[2], cpu_times2[2];
-
- os_cpu_times( cpu_times1 );
-
- os_notify_gc_begin( SCM_obj_to_int(pstate->id),
- (long)(sstate->globals[gc_report].value != (long)SCM_false) );
-
- if (pstate->heap_old > pstate->heap_bot)
- { pstate->heap_old = pstate->heap_bot;
- nb = pstate->heap_mid;
- nt = pstate->heap_top;
- }
- else
- { pstate->heap_old = pstate->heap_mid;
- nb = pstate->heap_bot;
- nt = pstate->heap_mid;
- }
-
- gc_flip( (char *)sstate, sstate->const_top, nb, nt, &fb, &ft );
-
- pstate->heap_lim = ((char *)fb) + pstate->heap_margin + (HEAP_ALLOCATION_FUDGE)*sizeof(SCM_obj);
- pstate->heap_ptr = (char *)ft;
-
- pstate->closure_lim = (char *)ft;
- pstate->closure_ptr = (char *)ft;
-
- os_notify_gc_end( SCM_obj_to_int(pstate->id), pstate->heap_mid, pstate->heap_bot, (char *)fb, (char *)ft,
- (long)(sstate->globals[gc_report].value != (long)SCM_false) );
-
- os_cpu_times( cpu_times2 );
-
- pstate->stats_counters[STAT_GC] += (cpu_times2[0] - cpu_times1[0]) +
- (cpu_times2[1] - cpu_times1[1]);
- }
-
-
- /*---------------------------------------------------------------------------*/
-
-
- #define gc_scan_closure(ptr,header) \
- gc_scan_range((SCM_obj *)ptr, SCM_closure_slots(header), (long)sizeof(SCM_obj))
-
-
- void gc_scan_roots()
- { long i, g, n, m;
- char *ptr, *limit;
-
- /* scan processor local storage (each processor has its own) */
-
- #ifdef DEBUG_GC
- scanned_object = 0;
- if (sstate->debug)
- { show_state();
- os_warn( "[%d: SCANNING processor local storage]\n", SCM_obj_to_int(pstate->id) );
- }
- #endif
-
- gc_scan_range( (SCM_obj *)pstate->processor_storage,
- (long)(sizeof(pstate->processor_storage) / sizeof(SCM_obj)),
- (long)sizeof(SCM_obj) );
-
- /* scan global vars (distribute work among processors) */
-
- #ifdef DEBUG_GC
- if (sstate->debug)
- { show_state();
- os_warn( "[%d: SCANNING global variables]\n", SCM_obj_to_int(pstate->id) );
- }
- #endif
-
- g = SCM_obj_to_int( sstate->globals[GLOBAL_VAR_COUNT].value );
- n = SCM_obj_to_int(pstate->nb_processors);
- m = g/n;
- if (SCM_obj_to_int(pstate->id) < (g%n)) m++;
- gc_scan_range( (SCM_obj *)&sstate->globals[SCM_obj_to_int(pstate->id)].value, m, n*sizeof(struct global_rec) );
-
- for (i=0; i<m; i++)
- sstate->globals[SCM_obj_to_int(pstate->id)+i*n].jump_adr =
- (long)&sstate->tramps[SCM_obj_to_int(pstate->id)+i*n];
-
- /* scan stack (each processor has an independent stack) */
-
- #ifdef DEBUG_GC
- if (sstate->debug)
- { show_state();
- os_warn( "[%d: SCANNING stack]\n", SCM_obj_to_int(pstate->id) );
- }
- #endif
-
- gc_scan_range( (SCM_obj *)pstate->stack_ptr,
- (long)(pstate->ltq_head[-1] - pstate->stack_ptr),
- (long)sizeof(SCM_obj) );
-
- /* scan work queue (each processor has its own) */
-
- #ifdef DEBUG_GC
- if (sstate->debug)
- os_warn( "[%d: SCANNING work queue]\n", SCM_obj_to_int(pstate->id) );
- #endif
-
- gc_scan_range( (SCM_obj *)&pstate->workq_head, 1L, (long)sizeof(SCM_obj) );
- gc_scan_range( (SCM_obj *)&pstate->workq_tail, 1L, (long)sizeof(SCM_obj) );
-
- /* scan current task (each processor has its own) */
-
- #ifdef DEBUG_GC
- if (sstate->debug)
- { show_state();
- os_warn( "[%d: SCANNING current task]\n", SCM_obj_to_int(pstate->id) );
- }
- #endif
-
- gc_scan_range( (SCM_obj *)&pstate->current_task, 1L, (long)sizeof(SCM_obj) );
- gc_scan_range( (SCM_obj *)&pstate->parent_ret, 1L, (long)sizeof(SCM_obj) );
- gc_scan_range( (SCM_obj *)&pstate->parent_frame, 1L, (long)sizeof(SCM_obj) );
- gc_scan_range( (SCM_obj *)&pstate->current_dyn_env, 1L, (long)sizeof(SCM_obj) );
- gc_scan_range( (SCM_obj *)&pstate->temp_task, 1L, (long)sizeof(SCM_obj) );
- gc_scan_range( (SCM_obj *)&pstate->response, 1L, (long)sizeof(SCM_obj) );
-
- /* scan constant space (each processor GCs its own copy) */
-
- #ifdef DEBUG_GC
- if (sstate->debug)
- { show_state();
- os_warn( "[%d: SCANNING constant space (with headers)]\n", SCM_obj_to_int(pstate->id) );
- }
- #endif
-
- ptr = sstate->const_bot;
- limit = sstate->const_bptr;
-
- while (ptr < limit)
- { long len, header =